-- Copyright (c) 2024 Huawei Technologies Co., Ltd.
-- openUBMC is licensed under Mulan PSL v2.
-- You can use this software according to the terms and conditions of the Mulan PSL v2.
-- You may obtain a copy of Mulan PSL v2 at:
--          http://license.coscl.org.cn/MulanPSL2
-- THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
-- EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
-- MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
-- See the Mulan PSL v2 for more details.
local mdb = require 'mc.mdb'
local class = require 'mc.class'
local app_base = require 'mc.service_app_base'
local object_manage = require 'mc.mdb.object_manage'

local TrustedComponentTypes = require 'spdm.json_types.TrustedComponent'
local PropertiesTypes = require 'spdm.json_types.Properties'
local ComponentIntegrityTypes = require 'spdm.json_types.ComponentIntegrity'
local MeasurementSetTypes = require 'spdm.json_types.MeasurementSet'
local SPDMMeasurementTypes = require 'spdm.json_types.SPDMMeasurement'
local CertificateTypes = require 'spdm.json_types.Certificate'

local TrustedComponent = mdb.register_object('/bmc/kepler/Chassis/:ChassisId/TrustedComponents/:DeviceName', {
    {name = 'bmc.kepler.RoT.TrustedComponent', interface = TrustedComponentTypes.interface},
    {name = 'bmc.kepler.Object.Properties', interface = PropertiesTypes.interface}
})

function TrustedComponent:ctor(ChassisId, DeviceName)
    self.path = '/bmc/kepler/Chassis/' .. ChassisId .. '/TrustedComponents/' .. DeviceName
end

local ComponentIntegrity = mdb.register_object(
    '/bmc/kepler/Chassis/:ChassisId/TrustedComponents/:DeviceName/ComponentIntegrity/:Id', {
        {name = 'bmc.kepler.RoT.ComponentIntegrity', interface = ComponentIntegrityTypes.interface},
        {name = 'bmc.kepler.RoT.ComponentIntegrity.MeasurementSet', interface = MeasurementSetTypes.interface},
        {name = 'bmc.kepler.Object.Properties', interface = PropertiesTypes.interface}
    })

function ComponentIntegrity:ctor(ChassisId, DeviceName, Id)
    self.path = '/bmc/kepler/Chassis/' .. ChassisId .. '/TrustedComponents/' .. DeviceName .. '/ComponentIntegrity/' ..
                    Id
end

local SPDMMeasurement = mdb.register_object(
    '/bmc/kepler/Chassis/:ChassisId/TrustedComponents/:DeviceName/ComponentIntegrity/:Id/Measurements/:Index', {
        {name = 'bmc.kepler.RoT.ComponentIntegrity.SPDMMeasurement', interface = SPDMMeasurementTypes.interface},
        {name = 'bmc.kepler.Object.Properties', interface = PropertiesTypes.interface}
    })

function SPDMMeasurement:ctor(ChassisId, DeviceName, Id, Index)
    self.path = '/bmc/kepler/Chassis/' .. ChassisId .. '/TrustedComponents/' .. DeviceName .. '/ComponentIntegrity/' ..
                    Id .. '/Measurements/' .. Index
end

local TrustedComponentCertificate = mdb.register_object(
    '/bmc/kepler/Chassis/:ChassisId/TrustedComponents/:DeviceName/Certificates/:SlotId', {
        {name = 'bmc.kepler.CertificateService.Certificate', interface = CertificateTypes.interface},
        {name = 'bmc.kepler.Object.Properties', interface = PropertiesTypes.interface}
    })

function TrustedComponentCertificate:ctor(ChassisId, DeviceName, SlotId)
    self.path = '/bmc/kepler/Chassis/' .. ChassisId .. '/TrustedComponents/' .. DeviceName .. '/Certificates/' .. SlotId
end

local model = require 'class.model'

local spdm_service = class(app_base.Service)

spdm_service.package = 'spdm'

function spdm_service:CreateTrustedComponent(ChassisId, DeviceName, prop_setting_cb)
    local path = '/bmc/kepler/Chassis/' .. ChassisId .. '/TrustedComponents/' .. DeviceName
    return object_manage.create_object('TrustedComponent', path, path, prop_setting_cb)
end

function spdm_service:CreateComponentIntegrity(ChassisId, DeviceName, Id, prop_setting_cb)
    local path = '/bmc/kepler/Chassis/' .. ChassisId .. '/TrustedComponents/' .. DeviceName .. '/ComponentIntegrity/' ..
                     Id
    return object_manage.create_object('ComponentIntegrity', path, path, prop_setting_cb)
end

function spdm_service:CreateSPDMMeasurement(ChassisId, DeviceName, Id, Index, prop_setting_cb)
    local path = '/bmc/kepler/Chassis/' .. ChassisId .. '/TrustedComponents/' .. DeviceName .. '/ComponentIntegrity/' ..
                     Id .. '/Measurements/' .. Index
    return object_manage.create_object('SPDMMeasurement', path, path, prop_setting_cb)
end

function spdm_service:CreateTrustedComponentCertificate(ChassisId, DeviceName, SlotId, prop_setting_cb)
    local path = '/bmc/kepler/Chassis/' .. ChassisId .. '/TrustedComponents/' .. DeviceName .. '/Certificates/' ..
                     SlotId
    return object_manage.create_object('TrustedComponentCertificate', path, path, prop_setting_cb)
end

function spdm_service:ImplComponentIntegrityMeasurementSetSPDMGetSignedMeasurements(cb)
    model.ImplComponentIntegrityMeasurementSetSPDMGetSignedMeasurements(cb)
end

function spdm_service:ImplTrustedComponentCertificateCertificateDeleteCRL(cb)
    model.ImplTrustedComponentCertificateCertificateDeleteCRL(cb)
end

function spdm_service:ImplTrustedComponentCertificateCertificateGetCertificateString(cb)
    model.ImplTrustedComponentCertificateCertificateGetCertificateString(cb)
end

function spdm_service:get_bus()
    return self.bus
end

function spdm_service:ctor()
    self.signal_slots = {}
    self.name = self.name or spdm_service.package

    self.bus:request_name(app_base.Service.get_service_name(self.name))
    model.init(self.bus)
    spdm_service.bus = self.bus
end

function spdm_service:pre_init()
    spdm_service.super.pre_init(self)
end

function spdm_service:init()
    spdm_service.super.init(self)
end

return spdm_service
